"""接口入口（实体情感分析接口）"""
"""
金融实体级情感分析平台API服务
提供RESTful API接口供客户端调用
"""
import uvicorn
from fastapi import FastAPI, Depends, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime
import time

# 导入项目模块
from fin_senti_entity_platform.service_deployment.api.dependencies import get_model_manager, get_security_manager
from fin_senti_entity_platform.service_deployment.api.response_models import (
    SentimentResponse, EntityResponse, BatchSentimentResponse,
    HealthResponse, ModelStatusResponse, ServiceStatusResponse
)
from fin_senti_entity_platform.service_deployment.api.request_models import (
    SentimentRequest, EntityRequest, BatchSentimentRequest
)
from fin_senti_entity_platform.utils.logger import Logger
from fin_senti_entity_platform.utils.config_loader import get_config
from fin_senti_entity_platform.utils.constants import HTTP_STATUS_CODES, SERVICE_STATUS

# 初始化日志
logger = Logger().get_logger(__name__)

# 初始化FastAPI应用
app = FastAPI(
    title="金融实体级情感分析平台API",
    description="提供金融文本的实体识别和情感分析服务",
    version="v1.0.0",
    docs_url="/docs",
    redoc_url="/redoc"
)

# 加载配置
config = get_config()

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=config.get('service', {}).get('api', {}).get('allowed_origins', ['*']),
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 添加请求-响应日志中间件
@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()
    
    # 记录请求信息
    logger.info(f"请求: {request.method} {request.url}")
    
    # 处理请求
    response = await call_next(request)
    
    # 计算处理时间
    process_time = time.time() - start_time
    
    # 记录响应信息
    status_text = HTTP_STATUS_CODES.get(response.status_code, '未知')
    logger.info(f"响应: {response.status_code} {status_text} - {process_time:.4f}秒")
    
    return response

# API路由
@app.get("/health", response_model=HealthResponse, tags=["健康检查"])
async def health_check():
    """健康检查接口"""
    return HealthResponse(
        status="健康",
        timestamp=datetime.now(),
        version=config.get('project', {}).get('version', 'v1.0.0')
    )

@app.get("/service/status", response_model=ServiceStatusResponse, tags=["服务状态"])
async def get_service_status(model_manager=Depends(get_model_manager)):
    """获取服务状态"""
    # 获取各模型状态
    model_statuses = {}
    for model_type in model_manager.models:
        model_statuses[model_type] = model_manager.get_model_status(model_type)
        
    return ServiceStatusResponse(
        status=SERVICE_STATUS.get('running', '运行中'),
        timestamp=datetime.now(),
        models=model_statuses,
        version=config.get('project', {}).get('version', 'v1.0.0')
    )

@app.get("/model/{model_type}/status", response_model=ModelStatusResponse, tags=["模型状态"])
async def get_model_status(model_type: str, model_manager=Depends(get_model_manager)):
    """获取指定模型的状态"""
    if model_type not in model_manager.models:
        raise HTTPException(status_code=404, detail=f"模型类型不存在: {model_type}")
        
    status = model_manager.get_model_status(model_type)
    return ModelStatusResponse(
        model_type=model_type,
        status=status.get('status', '未知'),
        is_trained=status.get('is_trained', False),
        last_updated=status.get('last_updated', datetime.now()),
        performance_metrics=status.get('performance_metrics', {})
    )

@app.post("/sentiment", response_model=SentimentResponse, tags=["情感分析"])
async def analyze_sentiment(
    request: SentimentRequest,
    model_manager=Depends(get_model_manager),
    security_manager=Depends(get_security_manager)
):
    """分析文本中实体的情感倾向"""
    try:
        # 数据安全检查
        if not security_manager.check_data_security(request.text):
            raise HTTPException(status_code=400, detail="输入文本包含敏感信息")
            
        # 调用模型进行分析
        start_time = time.time()
        result = model_manager.analyze_sentiment(request.text, request.entities)
        process_time = time.time() - start_time
        
        # 记录性能指标
        model_manager.record_performance(
            model_type='sentiment',
            latency=process_time,
            text_length=len(request.text),
            entity_count=len(request.entities)
        )
        
        return SentimentResponse(
            text=request.text,
            entities=result,
            processing_time=process_time,
            timestamp=datetime.now()
        )
        
    except Exception as e:
        logger.error(f"情感分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"情感分析失败: {str(e)}")

@app.post("/entity", response_model=EntityResponse, tags=["实体识别"])
async def recognize_entities(
    request: EntityRequest,
    model_manager=Depends(get_model_manager),
    security_manager=Depends(get_security_manager)
):
    """识别文本中的金融实体"""
    try:
        # 数据安全检查
        if not security_manager.check_data_security(request.text):
            raise HTTPException(status_code=400, detail="输入文本包含敏感信息")
            
        # 调用模型进行实体识别
        start_time = time.time()
        entities = model_manager.recognize_entities(request.text)
        process_time = time.time() - start_time
        
        # 记录性能指标
        model_manager.record_performance(
            model_type='entity',
            latency=process_time,
            text_length=len(request.text),
            entity_count=len(entities)
        )
        
        return EntityResponse(
            text=request.text,
            entities=entities,
            processing_time=process_time,
            timestamp=datetime.now()
        )
        
    except Exception as e:
        logger.error(f"实体识别失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"实体识别失败: {str(e)}")

@app.post("/batch/sentiment", response_model=BatchSentimentResponse, tags=["批量情感分析"])
async def batch_analyze_sentiment(
    request: BatchSentimentRequest,
    model_manager=Depends(get_model_manager),
    security_manager=Depends(get_security_manager)
):
    """批量分析文本中实体的情感倾向"""
    try:
        # 检查批量大小
        max_batch_size = config.get('service', {}).get('api', {}).get('max_batch_size', 100)
        if len(request.texts) > max_batch_size:
            raise HTTPException(status_code=400, detail=f"批量大小超过限制: {max_batch_size}")
            
        # 数据安全检查
        for text in request.texts:
            if not security_manager.check_data_security(text):
                raise HTTPException(status_code=400, detail="输入文本包含敏感信息")
                
        # 调用模型进行批量分析
        start_time = time.time()
        results = model_manager.batch_analyze_sentiment(request.texts, request.entities_list)
        process_time = time.time() - start_time
        
        # 记录性能指标
        total_entities = sum(len(entities) for entities in request.entities_list)
        model_manager.record_performance(
            model_type='batch_sentiment',
            latency=process_time,
            batch_size=len(request.texts),
            total_entities=total_entities
        )
        
        return BatchSentimentResponse(
            results=results,
            processing_time=process_time,
            batch_size=len(request.texts),
            timestamp=datetime.now()
        )
        
    except Exception as e:
        logger.error(f"批量情感分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"批量情感分析失败: {str(e)}")

# 启动服务
if __name__ == "__main__":
    host = config.get('service', {}).get('api', {}).get('host', '0.0.0.0')
    port = config.get('service', {}).get('api', {}).get('port', 8000)
    workers = config.get('service', {}).get('api', {}).get('workers', 4)
    
    logger.info(f"启动API服务，监听地址: {host}:{port}，工作进程数: {workers}")
    
    uvicorn.run(
        "src.service_deployment.api.main:app",
        host=host,
        port=port,
        workers=workers,
        reload=False
    )